﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ShareIt_MVC3.Models
{

    //Diese Klasse legt eine Struktur für den User fest.
    public class UserCollection
    {
        string _databaseFile;   // String zur Access-Datei, wird im Konstruktor initialisiert
 
        /// <summary>
        /// User-Collection Konstruktor 
        /// </summary>
        public UserCollection() 
        {
            _databaseFile = System.Configuration.ConfigurationManager.AppSettings["AccessFileName"];
        }


        /// <summary>
        /// Hilfsmethode für die Usercollection Klasse. Empfängt ein DataRow
        /// und gibt ein gefülltes Userobjekt zurück.
        /// </summary>
        /// <param name="_dr"></param>
        /// <returns></returns>
        private User CreateUserObject(DataRow _dr)
        {
            User user = new User
            {
                ID = (int)_dr["UID"],
                Username = (string)_dr["UUsername"],
                Name = (String)_dr["UName"],
                Surname = (String)_dr["USurname"],
                Address = (String)_dr["UAddress"],
                ZIP = (String)_dr["UZIP"],
                City = (String)_dr["UCity"],
                EMail = (String)_dr["UEmail"],
                Password = (String)_dr["UPassword"],
                Active = (bool)_dr["UActive"],
                IsAdmin = (bool)_dr["UIsAdmin"],
                Credits = (int)_dr["UCredits"]
            };

            return user;

        }

        /// <summary>
        /// Liest alle User aus der DB und gibt sie als Liste zurück
        /// </summary>
        /// <returns></returns>
        public List<User> GetAllUsers()
        {

            //Hier wird ein DB-Provider instanziiert und eine Verbindung zur Access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            

            //Hier wird unser Dataset aus der DB befüllt
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetAllUsers");
            List<User> _myUserList = new List<User>();
            DataTable _myDataTable;

            try
            {
                //das DataSet enthält nur eine DataTable
                _myDataTable = _myDataSet.Tables[0];
            }
            catch (IndexOutOfRangeException)
            {
                return _myUserList;
            }

            //Instantiieren eine Liste von User-Objekten
            

            //Lesen wir jetzt Zeile (DataRow) für Zeile
            foreach (DataRow _dr in _myDataTable.Rows)
            {
                _myUserList.Add(CreateUserObject(_dr));
            }
            return _myUserList;
        } //getAllUsers() 

        /// <summary>
        /// Update eines Userobjekts
        /// </summary>
        /// <param name="_User">User-Objekt mit geänderten Attributen</param>
        /// <returns>1 falls Update erfolgreich </returns>
        public int UpdateUser(User _User)
        {

            //DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            // Jetzt müssen wir erstmal die Übergabeparameter hinzufügen 
            // (Parameter in derselben Reihenfolge wie in der Access-Query)
            _myProvider.AddParam("Username", _User.Username, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Name", _User.Name, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Surname", _User.Surname, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Address", _User.Address, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("ZIP", _User.ZIP, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("City", _User.City, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("EMail", _User.EMail, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Password", _User.Password, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Active", _User.Active, DAL.DataDefinition.enumerators.SQLDataType.BOOL);
            _myProvider.AddParam("IsAdmin", _User.IsAdmin, DAL.DataDefinition.enumerators.SQLDataType.BOOL);
            _myProvider.AddParam("Credits", _User.Credits, DAL.DataDefinition.enumerators.SQLDataType.INT);
            _myProvider.AddParam("UID", _User.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);

            //Ausführen und veränderte Zeilen zurückgeben
            int _changedSets = _myProvider.MakeStoredProcedureAction("QUserUpdateById");

            return _changedSets;
        } //updateUser()

        /// <summary>
        /// Löschen eines Userobjekts
        /// </summary>
        /// <param name="_User">User-Objekt mit geänderten Attributen</param>
        /// <returns>1 falls delete erfolgreich </returns>
        public int DeleteUser(User _User)
        {

            //DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            // Übergabeparameter ID hinzufügen 
            _myProvider.AddParam("ID", _User.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);

            //Ausführen und veränderte Zeilen zurückgeben
            int _changedSets = _myProvider.MakeStoredProcedureAction("QUserDeleteById");

            return _changedSets;
        } //deleteUser()

        /// <summary>
        /// Insert eines Userobjekts
        /// </summary>
        /// <param name="_User">User-Objekt</param>
        /// <returns>1 falls Insert erfolgreich </returns>
        public int InsertUser(User _User)
        {

            //DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            // Jetzt müssen wir erstmal die Übergabeparameter hinzufügen 
            // (Parameter in derselben Reihenfolge wie in der Acess-Query)
            _myProvider.AddParam("Username", _User.Username, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Name", _User.Name, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Surname", _User.Surname, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Address", _User.Address, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("ZIP", _User.ZIP, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("City", _User.City, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("EMail", _User.EMail, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Password", _User.Password, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Active", _User.Active, DAL.DataDefinition.enumerators.SQLDataType.BOOL);
            _myProvider.AddParam("IsAdmin", _User.IsAdmin, DAL.DataDefinition.enumerators.SQLDataType.BOOL);
            _myProvider.AddParam("Credits", _User.Credits, DAL.DataDefinition.enumerators.SQLDataType.INT);

            //Ausführen und veränderte Zeilen zurückgeben
            int _changedSets = _myProvider.MakeStoredProcedureAction("QUserInsert");

            return _changedSets;
        } //updateUser()

        /// <summary>
        /// Gibt User nach einer ID zurück
        /// </summary>
        /// <param name="_id">ID des gesuchten Users</param>
        /// <returns>User-Objektt (oder NULL) </returns>
        public User GetUserById(int _id)
        {

            //Hier wird ein DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            
            //Jetzt müssen wir erstmal den Übergabeparameter hinzufügen
            _myProvider.AddParam("ID", _id, DAL.DataDefinition.enumerators.SQLDataType.INT);

            User _myUser = null;

            try
            {
                //Hier wird unser Dataset initialisiert
                DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetUserById");

                //füllen wir eine DataTable mit dem DataSet
                DataRow _dr = _myDataSet.Tables[0].Rows[0];
                _myUser = CreateUserObject(_dr);
            }
            catch { }
            

            return _myUser;
        } // getUserbyId()

        /// <summary>
        /// Gibt den gesuchten user zurück.
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>
        public User GetUserByUsername(string username)
        {
            //Hier wird ein DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);
            //Jetzt müssen wir erstmal den Übergabeparameter hinzufügen
            _myProvider.AddParam("username", username, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);

            User _myUser = null;
            //Hier wird unser Dataset initialisiert
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetUserByUsername");

            //füllen wir eine DataTable mit dem DataSet
            try
            {
                DataRow _dr = _myDataSet.Tables[0].Rows[0];
                _myUser = CreateUserObject(_dr);
            }
            catch
            {
                
            }
            

            return _myUser;
        }

        /// <summary>
        /// Gibt User nach dem Username zurück
        /// </summary>
        /// <param name="_id">Username des gesuchten Users</param>
        /// <returns>User-Objektt (oder NULL) </returns>
        public User GetUserByUsernameAndPassword(string _name, string _password)
        {

            //Hier wird ein DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            //Jetzt müssen wir erstmal den Übergabeparameter hinzufügen
            _myProvider.AddParam("Name", _name, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            _myProvider.AddParam("Password", _password, DAL.DataDefinition.enumerators.SQLDataType.VARCHAR);
            User _myUser = null;

            try
            {
                //Hier wird unser Dataset initialisiert
                DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QGetUserByUsernameAndPassword");

                //füllen wir eine DataTable mit dem DataSet
                DataRow _dr = _myDataSet.Tables[0].Rows[0];

                _myUser = CreateUserObject(_dr);
            }
            catch { }
            
            return _myUser;
        } // getUserbyId()

        /// <summary>
        /// Zählt Anzahl users via SQL-Abfrage
        /// </summary>
        /// <param name="_id"></param>
        /// <returns>Anzahl Users</returns>
        public int CountUsers1()
        {
            int _count;

            //Hier wird ein DB-Provider instanziiert und eine Verbindung zur access-Datenbank aufgebaut
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            //Hier wird unser Dataset initialisiert
            DataSet _myDataSet = _myProvider.GetStoredProcedureDSResult("QCountUsers");

            //das Ergebnis von QCountUsers ist eine Tabelle mit einer Zeile und einer Spalte
            DataRow _dr = _myDataSet.Tables[0].Rows[0];

            _count = (int)_dr[0];

            return _count;
        } // CountUsers1()

        /// <summary>
        /// Zählt Anzahl Users, indem erst alle eingelesen werden und dann Länge der Liste zurückgegeben wird
        /// </summary>
        /// <param name="_id"></param>
        /// <returns>Anzahl Users</returns>
        public int CountUsers2()
        {
            int _count;
            List<User> _UserList;

            _UserList = GetAllUsers();
            _count = _UserList.Count;

            return _count;
        } // CountUsers2()

        public int IncrementUserCredits(User user)
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            int changedSets = 0;
            //Jetzt müssen wir erstmal den Übergabeparameter hinzufügen
            _myProvider.AddParam("UID", user.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);

            try
            {
                //Hier wird unser Dataset initialisiert
                changedSets = _myProvider.MakeStoredProcedureAction("QIncrementUserCredits");
            }
            catch { }

            return changedSets;
            
        }

        /// <summary>
        /// Methode um die Credits des users zu verringern.
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public int DecrementUserCredits(User user)
        {
            DAL.DALObjects.dDataProvider _myProvider = DAL.DataFactory.GetAccessDBProvider(_databaseFile);

            int changedSets = 0;

            //Jetzt müssen wir erstmal den Übergabeparameter hinzufügen
            _myProvider.AddParam("UID", user.ID, DAL.DataDefinition.enumerators.SQLDataType.INT);

            try
            {
                //Hier wird unser Dataset initialisiert
                changedSets = _myProvider.MakeStoredProcedureAction("QDecrementUserCredits");
            }
            catch { }

            return changedSets;
        }
    }
}
